﻿using XW.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace XW.Core
{
    public static class CpHelper
    {
        private static Dictionary<string, Func<WhereFilter, string>> _dictionary = new Dictionary<string, Func<WhereFilter, string>>();
        static CpHelper()
        {
            var methods = typeof(Cp).GetMethods(BindingFlags.Static | BindingFlags.Public);
            foreach (var item in methods)
            {
                var temp = item;
                _dictionary.Add(item.Name.ToLower(), data => (string)temp.Invoke(null, new object[] { data }));
            }
        }

        public static Func<WhereFilter, string> Parse(string str, Func<WhereFilter, string> defaultCp = null)
        {
            str = (str ?? string.Empty).ToLower();
            return _dictionary.ContainsKey(str) ? _dictionary[str] : (defaultCp ?? Cp.Equal);
        }
    }
    public static class Cp
    {
        public static string Equal(WhereFilter data) { return SQL(data, "{0} =  '{1}'"); }
        public static string NotEqual(WhereFilter data) { return SQL(data, "{0} <> '{1}'"); }
        public static string Greater(WhereFilter data) { return SQL(data, "{0} >  '{1}'"); }
        public static string GreaterEqual(WhereFilter data) { return SQL(data, "{0} >= '{1}'"); }
        public static string DtGreaterEqual(WhereFilter data) { return SQL(data, "datediff(day,'{1}',{0}) >=0"); }
        public static string Less(WhereFilter data) { return SQL(data, "{0} < '{1}'"); }
        public static string LessEqual(WhereFilter data) { return SQL(data, "{0} <=  '{1}'"); }
        public static string DtLessEqual(WhereFilter data) { return SQL(data, "datediff(day,'{1}',{0}) < =0"); }
        public static string In(WhereFilter data) { return SQL(data, "{0} in({1})"); }
        public static string Like(WhereFilter data) { return SQL(data, "{0} like '%{1}%'"); }
        public static string StartWith(WhereFilter data) { return SQL(data, "{0} like '{1}%'"); }
        public static string StartWithPY(WhereFilter data) { return SQL(data, "{0} like '{1}%' or [dbo].[fun_getPY]({0}) like N'{1}%'"); }
        public static string EndWith(WhereFilter data) { return SQL(data, "{0} like '%{1}'"); }
        public static string Between(WhereFilter data) { return SQL(data, "{0} between '{1}'  '{0}'"); }
        public static string DateRange(WhereFilter data) { return GetDateRangeSql(data, '到'); }
        public static string Map(WhereFilter data) { return SQL(data, "{0} in (select {0} from {0} where {0}='{1}')"); }
        public static string Child(WhereFilter data) { return SQL(data, "{0} in (select ID from [dbo].[GetChild]('{0}','{1}'))"); }
        public static string MapChild(WhereFilter data) { return SQL(data, "{0} in (select {0} from {2} where {3} in (select ID from [dbo].[GetChild]('{4}','{1}')))"); }

        private static string SQL(WhereFilter cp, string stringFormat)
        {
            var list = cp.Extend.ToList();
            if (list == null)
            {
                list = new List<object>();
            }
            list.Insert(0, cp.Value);
            list.Insert(0, cp.Column);
            return string.Format(stringFormat, list.ToArray());
        }

        private static string GetDateRangeSql(WhereFilter cp, char _separator, bool _ignoreEmpty = true)
        {
            var sSql = string.Empty;
            var _from = "datediff(day,'{1}',{0}) >=0";
            var _to = "datediff(day,'{1}',{0})<=0";

            var values = CommonHelper.ToString(cp.Value).Split(_separator);

            if (values.Length == 1)
                values = new string[] { values[0], values[0] };

            if (!string.IsNullOrWhiteSpace(values[0]) || !_ignoreEmpty)
                sSql = string.Format(_from, cp.Column, values[0]);

            if (!string.IsNullOrWhiteSpace(values[1]) || !_ignoreEmpty)
                sSql += (sSql.Length > 0 ? " and " : string.Empty) + string.Format(_to, cp.Column, values[1]);

            return sSql;
        }
    }
}
